//==================================================================
//  Copyright (C) 2006  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
///
///
///
/// Where did I derive this from ? Forgot m(__)m ...
///
//==================================================================

#ifndef NOISE_H
#define NOISE_H

#include "Randomizer.h"

//==================================================================
#define MAX_DIMENSIONS		4					// Maximum number of dimensions in a noise object
#define MAX_OCTAVES			128					// Maximum # of octaves in an fBm object

//==================================================================
///
//==================================================================
class Noise
{
protected:
	int		_dims;						// Number of dimensions used by this object
	u_char	_n_map[256];				// Randomized map of indexes into buffer
	float	_n_buffer[256][MAX_DIMENSIONS];	// Random n-dimensional buffer

	float lattice(int ix, float fx, int iy=0, float fy=0, int iz=0, float fz=0, int iw=0, float fw=0)
	{
		int		n[4] = {ix, iy, iz, iw};
		float	f[4] = {fx, fy, fz, fw};

		int	idx = 0;

		for(int i=0; i<_dims; ++i)
			idx = _n_map[(idx + n[i]) & 0xFF];

		float fValue = 0;

		for(int i=0; i<_dims; ++i)
			fValue += _n_buffer[idx][i] * f[i];

		return fValue;
	}

public:
	//Noise()	{}
	Noise(int nDimensions, u_int nSeed)	{ Init(nDimensions, nSeed); }
	void Init(int nDimensions, u_int nSeed);
	float CalcNoise(float *f);
};

#endif
